
Public Class pointer(Of T)
    Implements ICloneable, IComparable(Of pointer(Of T)), IComparable(Of T), IComparable
    'as .net design, cannot acturally compare two pointers

    Protected p As T = Nothing

    Public Function instance() As T
        Return p
    End Function

    Public Sub setinstance(ByVal i As T)
        p = i
    End Sub

    Public Sub clear()
        p = Nothing
    End Sub

    Public Sub New()
        clear()
    End Sub

    Public Sub New(ByVal i As T)
        p = i
    End Sub

    Public Sub New(ByVal i As pointer(Of T))
        If Not i Is Nothing Then
            p = i.p
        Else
            p = Nothing
        End If
    End Sub

#If Not (PocketPC OrElse Smartphone) Then
    Public Shared Operator ^(ByVal p As pointer(Of T), ByVal jumps As Decimal) As Object
        On Error GoTo finish
        Dim p2 As Object
        p2 = p
        While jumps > 0
            p2 = +(convertor.cast(Of pointer(Of T))(p2, False))
            jumps -= 1
        End While
finish:
        Return p2
    End Operator
#End If

    Public Shared Operator +(ByVal p As pointer(Of T)) As T
        If Not p Is Nothing Then
            Return p.p
        Else
            Return Nothing
        End If
    End Operator

    'special treatment for pointer, it compares reference equaling, instead of internal object
    Public Shared Operator <>(ByVal this As pointer(Of T), ByVal that As pointer(Of T)) As Boolean
        Return Not this = that
    End Operator

    Public Shared Operator =(ByVal this As pointer(Of T), ByVal that As pointer(Of T)) As Boolean
        If that Is Nothing Then
            Return this Is Nothing OrElse this.p Is Nothing
        Else
            Return this = that.p
        End If
    End Operator

    Public Shared Operator <>(ByVal this As pointer(Of T), ByVal that As T) As Boolean
        Return Not this = that
    End Operator

    Public Shared Operator =(ByVal this As pointer(Of T), ByVal that As T) As Boolean
        If this Is Nothing Then
            Return that Is Nothing
        Else
            Return Object.ReferenceEquals(this.p, that)
        End If
    End Operator

    Public Shared Operator <>(ByVal this As T, ByVal that As pointer(Of T)) As Boolean
        Return Not this = that
    End Operator

    Public Shared Operator =(ByVal this As T, ByVal that As pointer(Of T)) As Boolean
        Return that = this
    End Operator

    Public Shared Operator =(ByVal this As pointer(Of T), ByVal obj As Object) As Boolean
        Dim that As pointer(Of T) = Nothing
        that = convertor.cast(Of pointer(Of T))(obj, False)
        If that Is Nothing Then
            Dim that2 As T = Nothing
            that2 = convertor.cast(Of T)(obj, False)
            Return this = that2
        Else
            Return this = that
        End If
    End Operator

    Public Shared Operator <>(ByVal this As pointer(Of T), ByVal obj As Object) As Boolean
        Return Not this = obj
    End Operator

    Public Shared Operator =(ByVal this As Object, ByVal that As pointer(Of T)) As Boolean
        Return that = this
    End Operator

    Public Shared Operator <>(ByVal this As Object, ByVal that As pointer(Of T)) As Boolean
        Return Not this = that
    End Operator

#If RETIRED Then
    Public Overrides Function Equals(ByVal obj As Object) As Boolean
        Return Me = convertor.cast(Of pointer(Of T))(obj)
    End Function
#End If

    'avoid deep copy here
    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim rtn As pointer(Of T) = Nothing
        rtn = alloc(Me)
        rtn.p = p

        Return rtn
    End Function

    Public Overrides Function ToString() As String
        Return Convert.ToString(p)
    End Function

    '<SecurityPermission(SecurityAction.Demand, UnmanagedCode:=True)> _
    'Public Function CompareTo(ByVal obj As Object) As Integer Implements System.IComparable.CompareTo
    '    Dim that As pointer(Of T) = Nothing
    '    that = convertor.cast(Of pointer(Of T))(obj, True)

    '    Dim lh As GCHandle = Nothing
    '    Dim rh As GCHandle = Nothing
    '    lh = GCHandle.Alloc(p, Runtime.InteropServices.GCHandleType.Weak)
    '    rh = GCHandle.Alloc(that.p, Runtime.InteropServices.GCHandleType.Weak)
    '    Dim rtn As Int32
    '    rtn = GCHandle.ToIntPtr(lh).ToInt64 - GCHandle.ToIntPtr(rh).ToInt64
    '    lh.Free()
    '    rh.Free()
    '    Return rtn
    'End Function

    Public Function CompareTo(ByVal that As T) As Int32 Implements IComparable(Of T).CompareTo
        'what compared here is the inner object
        Return compare(p, that)
    End Function

    'if that is nothing, return p.CompareTo(nothing) if existing
    Public Function CompareTo(ByVal that As pointer(Of T)) As Int32 Implements IComparable(Of pointer(Of T)).CompareTo
        Return CompareTo(+that)
    End Function

    'if obj is an object, think it's a reference of pointer(of T)
    Public Function CompareTo(ByVal obj As Object) As Integer Implements System.IComparable.CompareTo
        Return CompareTo(convertor.cast(Of pointer(Of T))(obj, False))
    End Function

#If RETIRED Then
    Public Shared Operator =(ByVal this As pointer(Of T), ByVal that As pointer(Of T)) As Boolean
        Return operatorEqual(this, that)
    End Operator

    Public Shared Operator <>(ByVal this As pointer(Of T), ByVal that As pointer(Of T)) As Boolean
        Return operatorUnequal(this, that)
    End Operator

    Public Shared Operator =(ByVal this As pointer(Of T), ByVal that As Object) As Boolean
        Return operatorEqual(this, that)
    End Operator

    Public Shared Operator <>(ByVal this As pointer(Of T), ByVal that As Object) As Boolean
        Return operatorUnequal(this, that)
    End Operator

    Public Shared Operator =(ByVal this As pointer(Of T), ByVal that As T) As Boolean
        Return operatorEqual(this, that)
    End Operator

    Public Shared Operator <>(ByVal this As pointer(Of T), ByVal that As T) As Boolean
        Return operatorUnequal(this, that)
    End Operator

    Public Shared Operator =(ByVal this As T, ByVal that As pointer(Of T)) As Boolean
        Return operatorEqual(that, this)
    End Operator

    Public Shared Operator <>(ByVal this As T, ByVal that As pointer(Of T)) As Boolean
        Return operatorUnequal(that, this)
    End Operator
#End If

    Public Overrides Function Equals(ByVal that As Object) As Boolean
        Return operatorEqual(Me, that)
    End Function

    Public Overrides Function GetHashCode() As Integer
        'what get hash here is also the inner object
        Return p.GetHashCode()
    End Function
End Class
